package org.springframework.web.servlet.ajax.json;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

/**
 * @author Charles Tassoni
 */

public class AjaxContext {
		private  static final String REQUEST_KEY = "reqeust";
		public static final String JSON_AJAX_KEY = "jsonAjax";
		static final String FLASH = "flash";
		static final String FLASH_DO_NOT_CLEAR_THIS_TIME = "doNotClearThisTime";

	   	private static ThreadLocal<Map> holder = new ThreadLocal<Map>();

	    public static JsonAjax getJson(){
	    	return (JsonAjax) internalGet(JSON_AJAX_KEY);
	    }

	    /**
	     * 
	     * @return True indicates we're reacting to an AJAX request.
	     */
	    public static boolean isXHR(){
	    	return "XMLHttpRequest".equals(getRequest().getHeader("X-Requested-With"));
	    }
	    
	    /**
	     * Based on Rails' flash, this method allows you to store information
	     * in the session that will last for exactly one redirect.  Specifically,
	     * you store values in a map that can be retrieved with 
	     * <code>session.getAttribute("flash")</code>.  One typical use relevant 
	     * to AJAX is to pass JavaScript that should be executed after a redirect
	     * @param key
	     * @param value
	     */
	    public static void putInFlash(Object key, Object value){
	    	Map flash = (Map) getRequest().getSession().getAttribute(FLASH);
	    	flash.put(key, value);
	    	
	    	Set doNotClearThisTime = (Set) flash.get(FLASH_DO_NOT_CLEAR_THIS_TIME);
	    	doNotClearThisTime.add(key);
	    }

	   static void setup(JsonAjax jsonAjax, HttpServletRequest request){
			Map map = new HashMap();
			map.put(JSON_AJAX_KEY, jsonAjax);
			map.put(REQUEST_KEY, request);
			holder.set(map);
			
	   }
	   
	   static void clear(){
		 	 holder.set(null);
		}
	   
	    private static HttpServletRequest getRequest(){
	    	return  (HttpServletRequest) internalGet(REQUEST_KEY);
	    }
	   
	   private static Object internalGet(String key){
		   Object obj = holder.get().get(key);
		   if(obj == null){
			   throw new IllegalStateException("Context is not currently holding a value associated with " + key + ".");
		   }
		   return obj;
	   }

}
